package org.will.ftppool;

import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by wangwei-ww on 2017/7/14.
 */
public abstract class AbstractFTPTemplate implements IFTPOpts {
    protected Logger logger = LoggerFactory.getLogger("ftp-pool");
    protected FTPClientPool ftpClientPool;

    public FTPClientPool getFtpClientPool() throws Exception {
        return ftpClientPool;
    }

    public void setFtpClientPool(FTPClientPool ftpClientPool) {
        this.ftpClientPool = ftpClientPool;
    }

    public FTPContent downloadFile(String path, String fileName, FTPContent.FTPContentType type) throws Exception {
        return downloadFile(path, fileName, null, type);
    }

    @Override
    public FTPContent downloadFile(String path, String fileName) throws Exception {
        return downloadFile(path, fileName, FTPContent.FTPContentType.BYTE);
    }

    public FTPContent downloadFile(String path, String fileName, String encoding, FTPContent.FTPContentType type) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("正在下载{}文件,ftpconfig:{}", fileName, getFtpClientPool().getFactory().getConfig());
        }
        FTPClient client = getFTPClient();
        boolean ret = changeDirectory(client, path);
        FTPContent ftpContent = new FTPContent();
        type = type == null ? FTPContent.FTPContentType.BYTE : type;
        try {
            if (ret) {
                switch (type) {
                    case BYTE:
                        ftpContent.setBytes(downloadFileByBytes(client, fileName));
                        break;
                    case STR:
                        ftpContent.setStr(performPerFileToString(client, fileName, encoding));
                        break;
                }
            }
        } catch (Exception e) {
            logger.error("下载文件{}异常", fileName, e);
            getFtpClientPool().invalidateObject(client);
            client = null;
            throw e;
        } finally {
            if (client != null) {
                getFtpClientPool().returnObject(client);
            }
        }
        return ftpContent;
    }

    protected FTPClient getFTPClient() throws Exception {
        FTPClient client = null;
        try {
            client = getFtpClientPool().borrowObject();
        } catch (Exception e) {
            logger.error("--- Fail to get FTPClient ---", e);
            throw e;
        }
        return client;
    }

    protected final boolean changeDirectory(FTPClient client, String path) throws Exception {
        boolean ret = client.changeWorkingDirectory(path);
        if (!ret) {
            logger.error("changeDirectory failed {}", path);
            throw new Exception(String.format("changeDirectory failed %s", path));
        }
        return ret;
    }

    abstract protected String performPerFileToString(FTPClient client, String fileName, String encoding) throws Exception;

    abstract protected byte[] downloadFileByBytes(FTPClient client, String fileName) throws Exception;
}
